package com.hfi.security.core.social.config;

import com.hfi.security.core.properties.SecurityProperties;
import com.hfi.security.core.social.SocialAuthenticationFilterPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionSignUp;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;

/**
 * @author ChangLiang
 * @date 2019/8/21
 */
@Configuration
@EnableSocial
public class SocialConfig extends SocialConfigurerAdapter {

    /**
     * 在浏览器环境下就可以不做处理
     */
    @Autowired(required = false)
    private SocialAuthenticationFilterPostProcessor socialAuthenticationFilterPostProcessor;

    @Autowired
    private DataSource dataSource;

    /**
     * 可能在demo项目中并不默认注册
     */
    @Autowired(required = false)
    private ConnectionSignUp connectionSignUp;

    @Autowired
    private SecurityProperties securityProperties;

    /**
     * connectionFactoryLocator就是根据条件来查找我们想要的connectionFactory
     * 在我们的系统中可能有很多的connectionFactory 比如qq的connectionFactory 微信的connectionFactory...
     *
     * TextEncryptor是对我们插入到userConnection表中的数据进行加解密
     * userConnection表中的数据是比较敏感的数据，如access_token之类的，
     *
     * @param connectionFactoryLocator
     * @return
     */
    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        if (connectionSignUp != null) {
            repository.setConnectionSignUp(connectionSignUp);
        }
        return repository;
    }

    @Bean
    public SpringSocialConfigurer hfiSocialSecurityConfig() {
        HfiSpringSocialConfigurer springSocialConfigurer =
                new HfiSpringSocialConfigurer(securityProperties.getSocial().getFilterProcessesUrl());
        // 配置我们自定义的signUp页面
        springSocialConfigurer.signupUrl(securityProperties.getBrowser().getSignUpUrl());
        // 配置我们的后处理器
        springSocialConfigurer.setSocialAuthenticationFilterPostProcessor(socialAuthenticationFilterPostProcessor);
        return springSocialConfigurer;
    }

    /**
     * spring boot已经帮我们将其放到了容器中了 可以autowired 也可以直接写到参数上
     */
    @Bean
    public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator) {
        return new ProviderSignInUtils(connectionFactoryLocator, getUsersConnectionRepository(connectionFactoryLocator));
    }
}
